package com.bw.publish.utils

import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import com.alibaba.sdk.android.oss.ClientConfiguration
import com.alibaba.sdk.android.oss.ClientException
import com.alibaba.sdk.android.oss.OSSClient
import com.alibaba.sdk.android.oss.ServiceException
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask
import com.alibaba.sdk.android.oss.model.GetObjectRequest
import com.alibaba.sdk.android.oss.model.GetObjectResult
import com.alibaba.sdk.android.oss.model.PutObjectRequest
import com.alibaba.sdk.android.oss.model.PutObjectResult
import com.bw.common.BaseApplication
import com.bw.common.utils.LogUtils
import java.io.IOException
import java.io.InputStream

/**
 * @author:created by hahajing
 * 时间：2024/5/8 0008
 * 企鹅号:444511958
 * 描述:
 */
object AliOssUtils {
    private val bucketName: String = "ivideobucket"
    private var oss: OSSClient

    init {
        getMetaData()
        oss = initOss(BaseApplication.getApplicationContext())
    }

    private fun getMetaData(){
        val packageManager = BaseApplication.getApplicationContext().packageManager
        val appInfo:ApplicationInfo = packageManager.getApplicationInfo(BaseApplication.getApplicationContext().packageName,PackageManager.GET_META_DATA)
        endPoint=appInfo.metaData["endPoint"].toString()
        accessId=appInfo.metaData["accessId"].toString()
        accessKeySecret=appInfo.metaData["accessKeySecret"].toString()
    }

    /**
     * 华北2（北京）OSS节点
     */
    private lateinit var endPoint: String
    private lateinit var accessId: String
    private lateinit var accessKeySecret:String

    private fun initOss(context: Context): OSSClient {
        val ossPlainTextAKSKCredentialProvider =
            OSSPlainTextAKSKCredentialProvider(accessId, accessKeySecret)
        val clientConfiguration = ClientConfiguration()
        clientConfiguration.connectionTimeout = 15 * 1000
        clientConfiguration.socketTimeout = 15 * 1000
        clientConfiguration.maxConcurrentRequest = 5
        clientConfiguration.maxErrorRetry = 2


        val ossClient =
            OSSClient(context, endPoint, ossPlainTextAKSKCredentialProvider, clientConfiguration)

        return ossClient
    }

    /**
     * 上传文件
     */
    fun uploadObject(
        objectKey: String,
        uploadFilePath: String,
        calback: Callback
    ) {
        val put =
            PutObjectRequest(bucketName, objectKey, uploadFilePath)

        put.progressCallback =
            OSSProgressCallback { request, currentSize, totalSize ->
                LogUtils.d(
                    "PutObject",
                    "currentSize: $currentSize totalSize: $totalSize"
                )
                calback.onProgress(currentSize,totalSize)
            }

        val task: OSSAsyncTask<*> = oss.asyncPutObject(
            put, object : OSSCompletedCallback<PutObjectRequest?, PutObjectResult?> {
                override fun onSuccess(request: PutObjectRequest?, result: PutObjectResult?) {

                    calback.onSuccess(true)
                }

                override fun onFailure(
                    request: PutObjectRequest?,
                    clientException: ClientException?,
                    serviceException: ServiceException?
                ) {
                    calback.onFailed(RuntimeException(clientException?.message +serviceException?.message))
                }

            }
        )
    }

    /**
     * 下载文件
     */
    fun downloadObject(objectkey:String,callback:Callback){
        // Construct an object download request

        // Construct an object download request
        val get = GetObjectRequest(bucketName, objectkey)

        val task: OSSAsyncTask<*> = oss.asyncGetObject(
            get,
            object :OSSCompletedCallback<GetObjectRequest?, GetObjectResult>{
                override fun onSuccess(request: GetObjectRequest?, result: GetObjectResult?) {

                    // Request succeeds
                    LogUtils.d("Content-Length", "" + result!!.getContentLength())

                    val inputStream: InputStream = result!!.objectContent

                    val buffer = ByteArray(2048)
                    var len: Int

                    try {
                        while (inputStream.read(buffer).also({ len = it }) != -1) {

                        }
                        callback.onSuccess(true)
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }

                override fun onFailure(
                    request: GetObjectRequest?,
                    clientException: ClientException?,
                    serviceException: ServiceException?
                ) {
                    callback.onFailed(RuntimeException(serviceException!!.message))
                }
            })

    }
}